<?php

class ArrayTool
{
    /**
     * arrayCross
     * about three times fast than keyBaseArrayCross
     * @param  array  $arr1
     * @param  array  $arr2
     * @return array
     */
    public static function arrayCross(array $arr1, array $arr2)
    {
        $minLen = min(count($arr1), count($arr2));
        $stack = [];
        //array_shift cost more time
        // while ($minLen--) {
        //     $stack[] = array_shift($arr1);
        //     $stack[] = array_shift($arr2);
        // }
        for ($i = 0; $i < $minLen; $i++) {
            $stack[] = $arr1[$i];
            $stack[] = $arr2[$i];
        }
        return array_merge($stack, array_slice(isset($arr1[$minLen]) ? $arr1 : $arr2, $minLen));
    }

    public static function stringCross(string $str1, string $str2)
    {
        $minLen = min(strlen($str1), strlen($str2));
        $str = '';
        for ($i = 0; $i < $minLen; $i++) {
            $str .= $str1[$i] . $str2[$i];
        }
        return $str . substr(isset($str1[$minLen]) ? $str1 : $str2, $minLen);
    }

    public static function multiArraySort(array $data, $field, $sortOrder = SORT_ASC, $sortType = SORT_NUMERIC)
    {
        if (count($data) > 1) {
            array_multisort(array_column($data, $field), $sortOrder, $sortType, $data);
        }
        return $data;
    }

    public static function keyBaseArrayCross(array $arr1, array $arr2)
    {
        $arr1Len = count($arr1);
        $arr2Len = count($arr2);
        $arr1 = array_combine(range(1, 1 + --$arr1Len * 2, 2), $arr1);
        $arr2 = array_combine(range(2, 2 + --$arr2Len * 2, 2), $arr2);
        $allArr = $arr1 + $arr2;
        ksort($allArr);
        return $allArr;
    }

    public static function arrayValueToString(array $data)
    {
        return array_map(function ($val) {
            return json_encode($val, JSON_UNESCAPED_UNICODE);
        }, $data);
    }

    public static function arrVal2Str(array $data)
    {
        foreach ($data as &$datum) {
            $datum = json_encode($datum, JSON_UNESCAPED_UNICODE);
        }
        return $data;
    }
}

// echo ini_get('memory_limit'), PHP_EOL;exit;
ini_set('memory_limit', '256M');

$arr1 = range(1, 400000);
$arr2 = range(200001, 600000);

timer('cross');
$r1 = ArrayTool::arrayCross($arr1, $arr2);
timer('cross');
timer('keyBaseCross');
$r2 = ArrayTool::keyBaseArrayCross($arr1, $arr2);
timer('keyBaseCross');
timer(true);

// var_dump($r1);

function timer($key = 'default')
{
    static $log = [];
    if ($key === true) {
        foreach ($log as $key => $val) {
            printf('item:%s, start:%s, end:%s, cost:%s' . PHP_EOL, $key, $val['start'], $val['end'], $val['cost']);
        }
        printf('memory usage: %s,  memory peak usage:%s', memoryConvert(memory_get_usage(true)), memoryConvert(memory_get_peak_usage(true)));
    }
    if (!isset($log[$key]['start'])) {
        $log[$key]['start'] = microtime(true);
    } else {
        $log[$key]['end'] = microtime(true);
        $log[$key]['cost'] = $log[$key]['end'] - $log[$key]['start'];
    }
}

function memoryConvert($size)
{
    $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
    return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i];
}
